package com.mfoyou.agent.web.utils.common;

import java.util.Calendar;
import java.util.Date;
import java.util.List;


/**
 * 计费规则实体类
 *
 * @author wb-zh270168
 */
public class MfoyouPriceV2 {

    /**
     * 起步价
     */
    private Integer baseAmount;
    /**
     * 默认距离(公里)
     */
    private Integer containDistance;
    /**
     * 默认重量(kg)
     */
    private Integer containWeight;
    /**
     * 默认时间(小时)
     */
    private Integer containHour;
    /**
     * 增加距离(公里)
     */
    private Integer incDistance;
    /**
     * 增加重量(kg)
     */
    private Integer incWeight;
    /**
     * 增加时间(小时)
     */
    private Integer incHour;
    /**
     * 增加费用(元)
     */
    private Integer addMoney;
    /**
     * 总增加距离
     */
    private Integer incDistanceAmount;
    /**
     * 总增加重量
     */
    private Integer incWeightAmount;
    /**
     * 总增加时间
     */
    private Integer incHourAmount;
    /**
     * 夜间计费规则, 可能存在不同时段的不同收费所以是列表存储
     */
    private List<SpacialTime> spacialTimes;

    /**
     * 费用规则生效时间
     */
    private Integer startTime;
    /**
     * 费用规则失效时间
     */
    private Integer endTime;

    public Integer getBaseAmount() {
        return baseAmount;
    }

    public void setBaseAmount(Integer baseAmount) {
        this.baseAmount = baseAmount;
    }

    public Integer getContainDistance() {
        return containDistance;
    }

    public void setContainDistance(Integer containDistance) {
        this.containDistance = containDistance;
    }

    public Integer getContainWeight() {
        return containWeight;
    }

    public void setContainWeight(Integer containWeight) {
        this.containWeight = containWeight;
    }

    public Integer getAddMoney() {
        return addMoney;
    }

    public void setAddMoney(Integer addMoney) {
        this.addMoney = addMoney;
    }

    public Integer getEndTime() {
        return endTime;
    }

    public void setEndTime(Integer endTime) {
        this.endTime = endTime;
    }

    public Integer getStartTime() {
        return startTime;
    }

    public void setStartTime(Integer startTime) {
        this.startTime = startTime;
    }

    public Integer getIncDistanceAmount() {
        return incDistanceAmount;
    }

    public void setIncDistanceAmount(Integer incDistanceAmount) {
        this.incDistanceAmount = incDistanceAmount;
    }

    public Integer getIncDistance() {
        return incDistance;
    }

    public void setIncDistance(Integer incDistance) {
        this.incDistance = incDistance;
    }

    public Integer getIncWeight() {
        return incWeight;
    }

    public void setIncWeight(Integer incWeight) {
        this.incWeight = incWeight;
    }

    public Integer getIncWeightAmount() {
        return incWeightAmount;
    }

    public void setIncWeightAmount(Integer incWeightAmount) {
        this.incWeightAmount = incWeightAmount;
    }

    public List<SpacialTime> getSpacialTimes() {
        return spacialTimes;
    }

    public void setSpacialTimes(List<SpacialTime> spacialTimes) {
        this.spacialTimes = spacialTimes;
    }


    public Integer getContainHour() {
        return containHour;
    }

    public void setContainHour(Integer containHour) {
        this.containHour = containHour;
    }

    public Integer getIncHour() {
        return incHour;
    }

    public void setIncHour(Integer incHour) {
        this.incHour = incHour;
    }

    public Integer getIncHourAmount() {
        return incHourAmount;
    }

    public void setIncHourAmount(Integer incHourAmount) {
        this.incHourAmount = incHourAmount;
    }

    /**
     * 夜间计费规则实体类
     */
    static class SpacialTime {
        /**
         * 开始时间
         */
        private Integer startTime;
        /**
         * 结束时间
         */
        private Integer endTime;
        /**
         * 加价费用
         */
        private Integer addMoney;

        public Integer getAddMoney() {
            return addMoney;
        }

        public void setAddMoney(Integer addMoney) {
            this.addMoney = addMoney;
        }

        public Integer getEndTime() {
            return endTime;
        }

        public void setEndTime(Integer endTime) {
            this.endTime = endTime;
        }

        public Integer getStartTime() {
            return startTime;
        }

        public void setStartTime(Integer startTime) {
            this.startTime = startTime;
        }
    }

    /**
     * 计算费用
     *
     * @param weight
     * @param distance
     * @param dt
     * @param type
     * @return
     */
    public PriceData calPriceData(Integer weight, Integer distance, Integer hour, Date dt, int type) {
        PriceData priceData = new PriceData();
        priceData.setServiceOrderGoodAmount(0);
        if (type == 4) {
            // 4-帮我做
            priceData.setServiceOrderStartAmount(getBaseAmountByTime(dt));
            priceData.setServiceOrderDistanceAmount(0);
            priceData.setServiceOrderWeightAmount(0);
            priceData.setServiceOrderHourAmount(getHourAmount(hour == null ? 0 : hour));
        } else if (type < 4) {
            // 1-帮我取, 2-帮我送, 3-帮我买
            priceData.setServiceOrderStartAmount(getBaseAmountByTime(dt));
            priceData.setServiceOrderDistanceAmount(getdistanceAmount(distance == null ? 0 : distance));
            priceData.setServiceOrderWeightAmount(getWeightAmount(weight == null ? 0 : weight));
            priceData.setServiceOrderHourAmount(getHourAmount(hour == null ? 0 : hour));
        } else {
            // 29-拉货
            priceData.setServiceOrderStartAmount(getBaseAmountByTime(dt));
            priceData.setServiceOrderDistanceAmount(getdistanceAmount(distance == null ? 0 : distance));
            priceData.setServiceOrderWeightAmount(getWeightAmount(weight == null ? 0 : weight));
            priceData.setServiceOrderHourAmount(getHourAmount(hour == null ? 0 : hour));
        }
        // 计算订单总费用
        priceData.makeOrderAmount();
        return priceData;
    }

    /**
     * 根据距离计算费用
     *
     * @param distance
     * @return
     */
    private Integer getdistanceAmount(Integer distance) {
        if (containDistance != null && distance > containDistance && incDistance != null && incDistanceAmount != null) {
            return (distance - containDistance - 1 + incDistance) / incDistance * incDistanceAmount;
        }
        return 0;
    }

    /**
     * 根据重量计算费用
     *
     * @param weight
     * @return
     */
    private Integer getWeightAmount(Integer weight) {
        if (containWeight != null && weight > containWeight && incWeight != null && incWeight > 0 && incWeightAmount != null && incWeightAmount > 0) {
            return (weight - containWeight - 1 + incWeight) / incWeight * incWeightAmount;
        }
        return 0;
    }

    /**
     * 根据时间计算费用
     *
     * @param hour
     * @return
     */
    private Integer getHourAmount(Integer hour) {
        if (containHour != null && hour > containHour && incHour != null && incHour > 0 && incHourAmount != null && incHourAmount > 0) {
            return (hour - containHour - 1 + incHour) / incHour * incHourAmount;
        }
        return 0;
    }

    /**
     * 根据时间判断初始价格
     *
     * @param dt
     * @return
     */
    private Integer getBaseAmountByTime(Date dt) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(dt);
        int time = calendar.get(Calendar.HOUR_OF_DAY) * 100 + calendar.get(Calendar.MINUTE);
        //兼容老版本价格计算
        if (startTime != null && endTime != null) {
            if (startTime < endTime) {
                return time < endTime && time > startTime ? baseAmount + addMoney : baseAmount;
            } else {
                return time < endTime || time > startTime ? baseAmount + addMoney : baseAmount;
            }

        } else if (spacialTimes != null && spacialTimes.size() > 0) {
            for (SpacialTime spacialTime : spacialTimes) {
                Integer startTime = spacialTime.getStartTime();
                Integer endTime = spacialTime.getEndTime();
                boolean conditionOne = (startTime < endTime && time > startTime && time < endTime);
                boolean conditionTwo = (startTime > endTime && time < startTime && time > endTime);
                if (conditionOne || conditionTwo) {
                    return baseAmount + spacialTime.getAddMoney();
                }
            }
        }
        return baseAmount;
    }
}
